package com.wuage.infrastructure.security;

/**
 * @author Shynin
 * @version 1.0
 * @date 2020-09-03 00:03
 */

import com.wuage.infrastructure.status.BizResultCode;
import com.wuage.infrastructure.utils.JwtUtils;
import com.wuage.infrastructure.utils.OpenGsonWrapper;
import com.wuage.infrastructure.utils.Response;
import com.fasterxml.jackson.core.JsonParseException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

/**
 * @author shynin
 * 验证成功当然就是进行鉴权
 * 登录成功之后走此类进行鉴权操作
 */
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

    public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws IOException, ServletException {

        String tokenHeader = request.getHeader(JwtUtils.TOKEN_HEADER);
        // 如果请求头中没有Authorization信息则直接放行了
        if (tokenHeader == null || !tokenHeader.startsWith(JwtUtils.TOKEN_PREFIX)) {
            chain.doFilter(request, response);
            return;
        }
        // 如果请求头中有token，则进行解析，并且设置认证信息
        try {
            SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
        } catch (MalformedJwtException | ExpiredJwtException e) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(OpenGsonWrapper.toJson(new Response<>(BizResultCode.JWT_ERROR)));
            return;
        }

        super.doFilterInternal(request, response, chain);
    }


    /**
     * 这里从token中获取用户信息并新建一个token
     * @param tokenHeader token
     * @return 用户信息
     */
    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) throws JsonParseException {
        String token = tokenHeader.replace(JwtUtils.TOKEN_PREFIX, "");
        Long id = JwtUtils.getUserId(token);
        String username = JwtUtils.getUsername(token);
        String role = JwtUtils.getUserRole(token);
        Long tenantId = JwtUtils.getUserTenantId(token);
        //把当前登录用户和当前线程绑定
        JwtUtils.bindLoginUser(new LoginUser(id, username, role, tenantId));
        if (!StringUtils.isEmpty(username)){
            return new UsernamePasswordAuthenticationToken(username, null,
                    Collections.singleton(new SimpleGrantedAuthority(role))
            );
        }
        return null;
    }
}
